package com.meida.module.bus.provider.api.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.alibaba.fastjson.util.TypeUtils;
import com.google.common.collect.Maps;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.utils.RedisUtils;
import com.meida.module.admin.provider.service.BaseUserService;
import com.meida.module.bus.client.entity.BusMaterialPlan100;
import com.meida.module.bus.client.entity.BusMaterialPlan200;
import com.meida.module.bus.client.entity.BusPurchase;
import com.meida.module.bus.client.entity.BusReport;
import com.meida.module.bus.client.entity.srmapi.oa.ApprovalBackReq;
import com.meida.module.bus.client.entity.srmapi.oa.BusOaApprovalSync;
import com.meida.module.bus.client.entity.srmapi.psmtosrm.PMSResultBody;
import com.meida.module.bus.provider.api.util.ApiConstants;
import com.meida.module.bus.provider.api.util.PmsApiUtil;
import com.meida.module.bus.provider.api.util.PmsOaUtil;
import com.meida.module.bus.provider.service.*;
import org.apache.http.client.utils.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
public class PmsOaApiService {
    @Autowired
    private BusOaApprovalSyncService syncService;
    @Autowired
    private BusMaterialService busMaterialService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private BusMaterialPlan100Service plan100Service;
    @Autowired
    private BusMaterialPlan200Service plan200Service;
    @Autowired
    private BusMaterialPackage100Service package100Service;
    @Autowired
    private BusMaterialPackage200Service package200Service;
    @Autowired
    private BusReportService busReportService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private PmsOaUtil pmsOaUtil;
    @Autowired
    private SyncSrmService syncSrmService;
    @Autowired
    private BaseUserService userService;
    @Autowired
    private PmsApiUtil pmsApiUtil;
    @Autowired
    private BusPurchaseService busPurchaseService;

    /**
     * 获取物资材料/分包 修正、追加审批流返回的结果转为对应的单据需要的状态
     * @param approvalStatus
     * @return
     */
    public Integer getPlanOrPackageState(Integer approvalStatus) {
        // OA审批驳回
        if(approvalStatus == 2) {
            return 3;//审核不过
        }
        // OA审批提交成功
        return 2;
    }

    public void oaApprovalBk(ApprovalBackReq approvalBackReq) throws Exception {
        Map<String, Object> searchMap = Maps.newHashMap();
        searchMap.put(ApiConstants.MAP_REQUESTID, approvalBackReq.getRequestId());
        Collection<BusOaApprovalSync> oaApprovalSyncs = syncService.listByMap(searchMap);
        if (0 == oaApprovalSyncs.size()) {
            StaticLog.info("该requestId无流程:" + approvalBackReq.getRequestId());
            return;
        }
        BusOaApprovalSync busOaApprovalSync = oaApprovalSyncs.stream().findFirst().get();
        // 流程状态
        Integer approvalStatus = approvalBackReq.getApprovalStatus();
        // 项目ID
        Long projectId = busOaApprovalSync.getProjectId();
        // 流程分类
        String flowNum = busOaApprovalSync.getFlowNum();
        // 专业分类
        String majorCode = busOaApprovalSync.getMajorCode();
        // 工程包号
        String packageNo = busOaApprovalSync.getPackageNo();
        String userId = busOaApprovalSync.getUserNm();
        String userNm = userService.getByProperty("userName", userId).getNickName();
        StaticLog.info("userNum---:" + busOaApprovalSync.getUserNm());
        //设置材料100/200、分包100/200 审批状态
        if (
            ApiConstants.ENGINEER_APPROVAL_WZ_100_UPD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_WZ_100_ADD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_WZ_200_UPD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_WZ_200_ADD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_FB_100_UPD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_FB_100_ADD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_FB_200_UPD.equals(flowNum)
                || ApiConstants.ENGINEER_APPROVAL_FB_200_ADD.equals(flowNum)
        ) {
            StaticLog.info("updApplyStatus-----start");
            Map applyMap = redisUtils.getMap(approvalBackReq.getRequestId());
            Collection<Object> reqS = (Collection<Object>) applyMap.get(ApiConstants.REDIS_KEY_PLAN_DATA_COLLECTION);
            // 修改状态
            Integer planOrPackageState = getPlanOrPackageState(approvalStatus);
            if(pmsOaUtil.updApplyStatus(reqS, flowNum, planOrPackageState)) {
                redisUtils.del(approvalBackReq.getRequestId());
                StaticLog.info("redisUtils.del(approvalBackReq.getRequestId())-----");
            }
            StaticLog.info("updApplyStatus-----start");
        }
        if (ApiConstants.APPROVAL_ING == approvalStatus) {
            StaticLog.info("--审批中---");
            return;
        } else if (ApiConstants.APPROVAL_REJECT == approvalStatus) {
            StaticLog.info("--审批驳回---");
            //处理OA审批驳回
            dealOaApprovalReject(approvalBackReq, approvalStatus, flowNum, projectId, userId, userNm);
        } else if(ApiConstants.APPROVAL_SUCCESS == approvalStatus) {
            //处理OA审批通过
            dealOaApprovalSuccess(busOaApprovalSync, approvalBackReq, userId, userNm);
        }
    }

    /**
     * 处理OA审批通过
     * @param approvalBackReq
     * @param userId
     * @param userNm
     */
    public void dealOaApprovalSuccess(BusOaApprovalSync busOaApprovalSync, ApprovalBackReq approvalBackReq, String userId, String userNm) throws Exception  {
        // 专业分类
        String majorCode = busOaApprovalSync.getMajorCode();
        // 工程包号
        String packageNo = busOaApprovalSync.getPackageNo();
        // 流程状态
        Integer approvalStatus = approvalBackReq.getApprovalStatus();
        // 项目ID
        Long projectId = busOaApprovalSync.getProjectId();
        // 流程分类
        String flowNum = busOaApprovalSync.getFlowNum();
        if (ApiConstants.BUSINESS_APPROVAL_100.equals(flowNum)) {
            // 工程量清单的100版本的审批
            StaticLog.info("工程量清单的100版本的审批--goArchive100---start");
            busMaterialService.goArchive100(projectId, approvalStatus);
            StaticLog.info("工程量清单的100版本的审批--goArchive100---end");

        } else if (ApiConstants.BUSINESS_APPROVAL_WZ_100.equals(flowNum)) {
            // 材料计划转的200版本审批
            StaticLog.info("材料计划转的200版本审批--goVersion200---start");
            // 材料计划转的200版本审批
            plan100Service.goVersion200(ApiConstants.APPROVAL_SUCCESS, projectId);
            StaticLog.info("材料计划转的200版本审批--goVersion200---end");

        } else if (ApiConstants.BUSINESS_APPROVAL_FB_100.equals(flowNum)) {
            // 分包计划转的200版本审批
            StaticLog.info("分包计划转的200版本审批--goArchive200---start");
            // 分包计划转的200版本审批
            package100Service.goArchive200(projectId, ApiConstants.APPROVAL_SUCCESS);
            StaticLog.info("分包计划转的200版本审批--goArchive200---end");
        } else if (ApiConstants.BUSINESS_APPROVAL_FB_CONTACTS.equals(flowNum)) {
            // 分包合同下达审批
            StaticLog.info("分包合同下达审批--saveBusReportAfter---start");

            StaticLog.info("分包合同下达审批--saveBusReportAfter---end");
        } else if (ApiConstants.BUSINESS_APPROVAL_REPORT_OUT.equals(flowNum)) {
            // 对外验工月报审批

        } else if (ApiConstants.ENGINEER_APPROVAL_WZ_100_UPD.equals(flowNum)) {
            // 材料计划_100版本_修正变更审批
            StaticLog.info("材料计划_100版本_修正变更审批--goMerge100---start");
            // 材料计划_100版本_修正变更审批
            plan100Service.goMerge100(approvalStatus, projectId);
            StaticLog.info("材料计划_100版本_修正变更审批--goMerge100---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_WZ_100_ADD.equals(flowNum)) {
            // 材料计划_100版本_追加变更审批
            StaticLog.info("材料计划_100版本_追加变更审批--goMerge100---start");
            // 材料计划_100版本_追加变更审批
            plan100Service.goMerge100(approvalStatus, Long.valueOf(projectId));
            StaticLog.info("材料计划_100版本_追加变更审批--goMerge100---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_WZ_200_UPD.equals(flowNum)) {
            // 材料计划_200版本_修正变更审批
            StaticLog.info("材料计划_200版本_修正变更审批--gomergeplan200---start");
            // 材料计划_200版本_修正变更审批
            plan200Service.gomergeplan200(approvalStatus, projectId);
            StaticLog.info("材料计划_200版本_修正变更审批--gomergeplan200---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_WZ_200_ADD.equals(flowNum)) {
            // 材料计划_200版本_追加变更审批
            StaticLog.info("材料计划_200版本_追加变更审批--gomergeplan200---start");
            // 材料计划_200版本_追加变更审批
            plan200Service.gomergeplan200(approvalStatus, projectId);
            StaticLog.info("材料计划_200版本_追加变更审批--gomergeplan200---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_FB_100_UPD.equals(flowNum)) {
            // 分包计划_100版本_修正变更审批
            StaticLog.info("分包计划_100版本_修正变更审批--goMerge100---start");
            package100Service.goMerge100(projectId, packageNo, majorCode, userNm);
            StaticLog.info("分包计划_100版本_修正变更审批--goMerge100---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_FB_100_ADD.equals(flowNum)) {
            // 分包计划_100版本_追加变更审批
            StaticLog.info("分包计划_100版本_追加变更审批--goMerge100---start");
            if (StrUtil.isNotEmpty(userNm)) {
                package100Service.goMerge100(projectId, packageNo, majorCode, userNm);
            } else {
                throw new Exception("redis 保存失败 requestId " + approvalBackReq.getRequestId());
            }
            StaticLog.info("分包计划_100版本_追加变更审批--goMerge100---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_FB_200_UPD.equals(flowNum)) {
            // 分包计划_200版本_追加变更审批
            StaticLog.info("分包计划_200版本_修正变更审批--goMerge200---start");
            if (StrUtil.isNotEmpty(userNm)) {
                package200Service.goMerge200(projectId, packageNo, majorCode, userNm);
            } else {
                throw new Exception("redis 保存失败 requestId " + approvalBackReq.getRequestId());
            }
            StaticLog.info("分包计划_200版本_修正变更审批--goMerge200---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_FB_200_ADD.equals(flowNum)) {
            // 分包计划_200版本_追加变更审批
            StaticLog.info("分包计划_200版本_追加变更审批--goMerge200---start");
            if (StrUtil.isNotEmpty(userNm)) {
                package200Service.goMerge200(projectId, packageNo, majorCode, userNm);
            } else {
                throw new Exception("redis 保存失败 requestId " + approvalBackReq.getRequestId());
            }
            StaticLog.info("分包计划_200版本_追加变更审批--goMerge200---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_WZ_REQ.equals(flowNum)) {
            StaticLog.info("材料计划申请_审批-回调用-goPurseSuccess---start");
            Map applyMap = redisUtils.getMap(approvalBackReq.getRequestId());
            BusPurchase purchase = (BusPurchase) applyMap.get("purchase");
            // 材料计划申请_审批
            ResultBody resultBody = null;
            if(pmsApiUtil.getLastVer(projectId, 0)) {
                List<BusMaterialPlan100> pnlist = (List<BusMaterialPlan100>) applyMap.get("plan100detail");
                resultBody = plan100Service.goPurseSuccess(ApiConstants.APPROVAL_SUCCESS, projectId, pnlist, purchase, userNm);
            } else {
                List<BusMaterialPlan200> pnlist = (List<BusMaterialPlan200>) applyMap.get("plan200detail");
                resultBody = plan200Service.goPurseSuccess(ApiConstants.APPROVAL_SUCCESS, projectId, pnlist, purchase, userNm);
            }
            redisUtils.del(approvalBackReq.getRequestId());
            StaticLog.info("材料计划申请_审批-回调用-goPurseSuccess---end");

        } else if (ApiConstants.ENGINEER_APPROVAL_FB_REQ.equals(flowNum)) {
            // 对内验工月报_审批
            StaticLog.info("对内验工月报_审批--saveBusReportAfter---start");
            Map approvalMap = redisUtils.getMap(approvalBackReq.getRequestId());
            List<BusReport> busReportsOut = (List<BusReport>) approvalMap.get(ApiConstants.REDIS_KEY_BUSREPORT_APPROVALS);
            //将审批状态置为审核通过
            busReportService.mergeAuditState(ApiConstants.APPROVAL_SUCCESS, busReportsOut);
            Integer ver = Integer.valueOf(String.valueOf(approvalMap.get(ApiConstants.REDIS_KEY_BUSREPORT_VER)));
            syncSrmService.busReportServiceImpl(busReportsOut, ver);
            redisUtils.del(approvalBackReq.getRequestId());
            StaticLog.info("对内验工月报_审批--saveBusReportAfter---end");
        }
    }

    /**
     * 处理OA审批驳回
     * @param approvalStatus 流程状态
     * @param flowNum 流程分类
     * @param projectId 项目ID
     */
    public void dealOaApprovalReject(ApprovalBackReq approvalBackReq, Integer approvalStatus, String flowNum, Long projectId, String userId, String userNm) {
        //材料计划申请_审批驳回
        if (ApiConstants.ENGINEER_APPROVAL_WZ_REQ.equals(flowNum)) {
            StaticLog.info("材料计划申请_审批驳回-回调用-goPurseSuccess---start");
            Map applyMap = redisUtils.getMap(approvalBackReq.getRequestId());
            BusPurchase purchase = (BusPurchase) applyMap.get("purchase");
            // 材料计划申请_审批
            ResultBody resultBody = null;
            if(pmsApiUtil.getLastVer(projectId, 0)) {
                List<BusMaterialPlan100> pnlist = (List<BusMaterialPlan100>) applyMap.get("plan100detail");
                resultBody = plan100Service.goPurseSuccess(ApiConstants.APPROVAL_REJECT, projectId, pnlist, purchase, userNm);

            } else {
                List<BusMaterialPlan200> pnlist = (List<BusMaterialPlan200>) applyMap.get("plan200detail");
                resultBody = plan200Service.goPurseSuccess(ApiConstants.APPROVAL_REJECT, projectId, pnlist, purchase, userNm);
            }
            redisUtils.del(approvalBackReq.getRequestId());
            StaticLog.info("材料计划申请_审批驳回-回调用-goPurseSuccess---end");
        }
        //验工月报审批驳回
        if(ApiConstants.ENGINEER_APPROVAL_FB_REQ.equals(flowNum)) {
            // 对内验工月报_审批
            StaticLog.info("对内验工月报_审批驳回--saveBusReportAfter---start");
            Map approvalMap = redisUtils.getMap(approvalBackReq.getRequestId());
            List<BusReport> busReportsOut = (List<BusReport>) approvalMap.get(ApiConstants.REDIS_KEY_BUSREPORT_APPROVALS);
            //将审批状态置为驳回
            busReportService.mergeAuditState(ApiConstants.APPROVAL_FAIL, busReportsOut);
            redisUtils.del(approvalBackReq.getRequestId());
            StaticLog.info("对内验工月报_审批驳回--saveBusReportAfter---end");
        }
        //物资材料100
        if (ApiConstants.ENGINEER_APPROVAL_WZ_100_UPD.equals(flowNum)
            || ApiConstants.ENGINEER_APPROVAL_WZ_100_ADD.equals(flowNum)){
            plan100Service.goVersion200(approvalStatus, projectId);
        }
        //物资材料200
        if (ApiConstants.ENGINEER_APPROVAL_WZ_200_UPD.equals(flowNum)
            || ApiConstants.ENGINEER_APPROVAL_WZ_200_ADD.equals(flowNum)){
            //TODO 接口未提供
        }
        //分包100
        if (ApiConstants.ENGINEER_APPROVAL_FB_100_UPD.equals(flowNum)
            || ApiConstants.ENGINEER_APPROVAL_FB_100_ADD.equals(flowNum)){
            package100Service.goArchive200(projectId, approvalStatus);
        }
        //分包200
        if (ApiConstants.ENGINEER_APPROVAL_FB_200_UPD.equals(flowNum)
            || ApiConstants.ENGINEER_APPROVAL_FB_200_ADD.equals(flowNum)){
            //TODO 接口未提供
        }
        //100材料转200 审批驳回
        if (ApiConstants.BUSINESS_APPROVAL_WZ_100.equals(flowNum)){
            //TODO 接口未提供
        }


    }

    public void syncApproval(Long projectId) {
        restTemplate.postForObject("http://192.168.50.78:8010/oaplat/alter", "", String.class);

    }
}
